package xyz.yq56.easytool.utils.log;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;

import lombok.extern.slf4j.Slf4j;
import xyz.yq56.easytool.utils.collection.CollectUtil;
import xyz.yq56.easytool.utils.json.JsonUtils;
import xyz.yq56.easytool.utils.nvll.NullUtil;
import xyz.yq56.easytool.utils.string.TextUtils;

/**
 * 构建结构化日志,让日志打印不再随心所欲
 *
 * @author yi qiang
 * @date 2021/9/20 10:33
 */
@Slf4j
public class LogUtil {

    private LogUtil() {
    }

    public static void error(String pre, Throwable e, Map<String, Object> map) {
        log.error(getLog("Error", pre, e, map), e.getMessage(), e);
    }

    public static void warn(String pre, Throwable e, Map<String, Object> map) {
        log.warn(getLog("Warn", pre, e, map), e.getMessage(), e);
    }

    public static void warn(String pre, Map<String, Object> map) {
        log.warn(getLog("Warn", pre, map), TextUtils.join(map.values(), ","));
    }

    public static void info(String pre, Map<String, Object> map) {
        if (log.isInfoEnabled()) {
            log.info(getLog("Info", pre, map));
        }
    }

    public static void debug(String pre, Map<String, Object> map) {
        if (log.isDebugEnabled()) {
            log.debug(getLog("Debug", pre, map));
        }
    }

    private static String getLog(String level, String pre, Throwable e, Map<String, Object> map) {
        return level + ": " + pre + " | " + getCurrentTrace(e) + " | msg: {} | " + TextUtils.join(buildLogList(map), ",");
    }

    private static String getLog(String level, String pre, Map<String, Object> map) {
        return level + ": " + pre + " | " + TextUtils.join(buildLogList(map), ",");
    }

    private static List<String> buildLogList(Map<String, Object> map) {
        List<String> logs = Lists.newArrayList();
        if (!CollectUtil.isEmpty(map)) {
            map.forEach((key, value) -> logs.add(key + ": " + JsonUtils.toJson(value)));
        }
        return logs;
    }

    private static String getCurrentTrace(Throwable e) {
        if (!NullUtil.isNull(e) && !NullUtil.isEmpty(e.getStackTrace())) {
            return String.valueOf(e.getStackTrace()[0]);
        }
        return "";
    }

}
